package com.example.joke.custom.textcolor

import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Rect
import android.util.AttributeSet
import android.widget.TextView
import com.example.joke.R

class ColorTrackTextView : TextView {

    var mOriginColor = Color.BLACK
    var mChangeColor = Color.RED
    private var mPaintOrigin: Paint
    private var mPaintChange: Paint
    var mCurrentProgress: Float = 0F
        set(value) {
            field = value
            invalidate()
        }

    var mDirection: Direction = Direction.LEFT_TO_RIGHT

    enum class Direction {
        LEFT_TO_RIGHT, RIGHT_TO_LEFT
    }
    constructor(context: Context?) : this(context, null)
    constructor(context: Context?, attrs: AttributeSet?) : this(context, attrs, 0)
    constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(
        context,
        attrs,
        defStyleAttr
    ) {
        val typedArray = context?.obtainStyledAttributes(attrs, R.styleable.ColorTrackTextView)
        mOriginColor = typedArray!!.getColor(R.styleable.ColorTrackTextView_originColor, mOriginColor)
        mChangeColor = typedArray.getColor(R.styleable.ColorTrackTextView_changeColor, mChangeColor)
        typedArray.recycle()

        mPaintOrigin = initPaint(mOriginColor)
        mPaintChange = initPaint(mChangeColor)
    }

    private fun initPaint(color: Int): Paint {
        val paint = Paint()
        paint.isAntiAlias = true
        paint.color = color
        // 防抖动
        paint.isDither = true
        // 获取的textview的字体大小
        paint.textSize = textSize
        return paint
    }

    override fun onDraw(canvas: Canvas?) {
        // 计算基线，得到绘制text的y坐标
        val fontMetrics = mPaintOrigin.fontMetricsInt
        val dy = (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.bottom
        val baseLine = height / 2 + dy
        // 注：基线x坐标为0的话，无论textview控件宽度多少，都会从最左面开始绘制文字
//        canvas?.drawText(text.toString(), 0F, baseLine.toFloat(), mPaintOrigin)
        // 设置android:gravity="center"和android:paddingLeft="10dp"也不会起作用，因为并没有针对这些属性对基线x位置做处理
        // 这里无论textview控件宽度多少，需求只要文字居中显示，所以x坐标计算如下
        val rect = Rect()
        mPaintOrigin.getTextBounds(text.toString(), 0, text.toString().length, rect)
        val x = width / 2 - rect.width() / 2

        val middle = (mCurrentProgress * width).toInt()

        if (mDirection == Direction.LEFT_TO_RIGHT) {    // 左边是红色，右边是黑色
//            canvas?.save()
//            canvas?.clipRect(0, 0, middle, height)
//            // 绘制变色部分
//            canvas?.drawText(text.toString(), x.toFloat(), baseLine.toFloat(), mPaintChange)
//            canvas?.restore()
//
//            canvas?.save()
//            canvas?.clipRect(middle, 0, width, height)
//            // 绘制不变色部分
//            canvas?.drawText(text.toString(), x.toFloat(), baseLine.toFloat(), mPaintOrigin)
//            canvas?.restore()
            drawText(canvas, x, baseLine, 0, middle, mPaintChange)
            drawText(canvas, x, baseLine, middle, width, mPaintOrigin)
        } else {        // 左边是黑色，右边是红色，
//            canvas?.save()
//            canvas?.clipRect(0, 0, width - middle, height)
//            // 绘制不变色部分
//            canvas?.drawText(text.toString(), x.toFloat(), baseLine.toFloat(), mPaintOrigin)
//            canvas?.restore()
//
//            canvas?.save()
//            canvas?.clipRect(width -  middle, 0, width, height)
//            // 绘制变色部分
//            canvas?.drawText(text.toString(), x.toFloat(), baseLine.toFloat(), mPaintChange)
//            canvas?.restore()
            drawText(canvas, x, baseLine, 0, width - middle, mPaintOrigin)
            drawText(canvas, x, baseLine, width - middle, width, mPaintChange)
        }

    }

    private fun drawText(
        canvas: Canvas?,
        x: Int,
        baseLine: Int,
        start: Int,
        end: Int,
        paint: Paint
    ) {
        canvas?.save()
        canvas?.clipRect(start, 0, end, height)
        // 绘制变色部分
        canvas?.drawText(text.toString(), x.toFloat(), baseLine.toFloat(), paint)
        canvas?.restore()
    }
}